(function () {
    "use strict";

    angular.module('core').controller('saidaDetailController', controller);
    controller.$inject = ['$scope', '$state', '$stateParams', '$q', '$alert', 'saidaService', 'lookupService', 'codigoBarraService', 'notaFiscalService', 'serieNFService'];

    function controller($scope, $state, $stateParams, $q, $alert, saidaService, lookupService, codigoBarraService, notaFiscalService, serieNFService) {

        $scope.initializeLayout('Saída de Mercadorias');

        //[Inicializa objetos]
        $scope.state = {
            item: { ID: decodeURIComponent($stateParams.id) },
            carregando: false,
            vazio: false
        };
        $scope.popups = {
            item: {
                auxNatureza: {},
                ativo: false,
                carregando: false,
                filtro: { codigoProduto: null, entity: { codigoProdutoOuBarras: '' } },
                prepareItem: function () {
                    saidaService
                        .prepare({ item: $scope.state.item })
                        .then(
                            function (response) {
                                if (response.Status < 0) {
                                    $alert({ text: response.Message, title: $scope.Title });
                                } else {
                                    $scope.popups.item.ativo = false;
                                    $scope.state.item = response.Data;

                                }
                                $scope.popups.item.ativo = false;
                            },
                            function (_error) {
                                $scope.popups.item.ativo = false;
                                $scope.tools.toastr.error('Não foi possível conectar com o(s) servidor(es)');
                            });
                },
                prepareNewItem: function () {


                    if (!$scope.popups.item.filtro.entity.codigoProdutoOuBarras)
                        return;

                    $scope.popups.item.carregando = true;

                    var args = {
                        codigoProdutoOuBarras: $scope.popups.item.filtro.entity.codigoProdutoOuBarras,
                        item: $scope.state.item
                    };

                    saidaService
                        .prepareNewItem(args)
                        .then(
                            function (response) {
                                if (response.Status < 0) {
                                    $alert({ text: response.Message, title: $scope.Title });
                                } else {

                                    $scope.state.item = response.Data;
                                    $scope.popups.item.prepareFiltroProduto();
                                    $scope.popups.item.ativo = true;
                                }
                                $scope.popups.item.carregando = false;
                            },
                            function (_error) {
                                $scope.popups.item.carregando = false;
                                $scope.tools.toastr.error('Não foi possível conectar com o(s) servidor(es)');
                            });
                },
                prepareFiltroProduto: function () {
                    /* Após preparar o item pelo código de barras, descobre o 
                     código do produto bipado para filtrar a edição do item
                     alimentando a propriedade codigoProduto. */
                    var args = { codigoBarra: $scope.popups.item.filtro.entity.codigoProdutoOuBarras };

                    codigoBarraService
                        .get(args)
                        .then(
                            function (response) {
                                if (response.Status >= 0) {

                                    if (response.Data)
                                        $scope.popups.item.filtro.entity.codigoProdutoOuBarras = response.Data.SKU.Produto.Codigo;

                                }
                            });
                }
            },
            emissao: {
                data: {
                    exito: false,
                    mensagem: "",
                },
                ativo: false,
                processando: false,
                toggle: async () => {
                    $scope.popups.emissao.ativo = !$scope.popups.emissao.ativo;
                    $scope.popups.emissao.steps.index = 0;
                    if ($scope.popups.emissao.ativo) {
                        await $scope.auxiliar.serie.getAll();
                        $scope.$digest();
                    }
                },
                run: async () => {
                    $scope.popups.emissao.steps.next();
                    $scope.popups.emissao.processando = true;
                    $scope.popups.emissao.data.exito = true;
                    $scope.popups.emissao.data.mensagem = "Emitindo a nota fiscal, por favor aguarde...";
                    try {
                        const response = await saidaService.enviarEmissaoSefaz($scope.state.item);
                        if (response.Status < 0) {
                            $scope.popups.emissao.data.exito = false;
                            $scope.popups.emissao.data.mensagem = response.Message;
                        } else {
                            $scope.popups.emissao.data.exito = true;
                            $scope.popups.emissao.data.mensagem = `Nota Fiscal emitida com êxito. ${response.Message}`;
                        }
                        $scope.state.item = response.Data;
                        
                    } catch (error) {
                        $scope.popups.emissao.data.exito = false;
                        $scope.popups.emissao.data.mensagem = error;
                    } finally {
                        $scope.popups.emissao.processando = false;
                        $scope.$digest();
                    }
                },
                selectNumeroModeloFiscal: () => {
                    const serie = $scope.auxiliar.serie.data.find(a => a.Codigo == $scope.state.item.SugestaoNotaFiscal?.CodigoSerie);
                    if (serie)
                        $scope.state.item.SugestaoNotaFiscal.NumeroModeloFiscal = serie.Especie?.NumeroModeloFiscal;
                },
                steps: {
                    index: 0,
                    run: 2,
                    last: 3,
                    next: function () {
                        if ($scope.popups.emissao.steps.index < $scope.popups.emissao.steps.last)
                            $scope.popups.emissao.steps.index++;
                    },
                    prior: function () {
                        if ($scope.popups.emissao.steps.index > 0)
                            $scope.popups.emissao.steps.index--;
                    }
                },
            },
            cancelamento: {
                ativo: false,
                processando: false,
                toggle: async () => {
                    $scope.popups.cancelamento.ativo = !$scope.popups.cancelamento.ativo;
                },
                run: async () => {
                    try {
                        if ($scope.popups.cancelamento.processando)
                            return;

                        $scope.popups.cancelamento.processando = true;

                        const response = await saidaService.enviarCancelamentoSefaz($scope.state.item);

                        if (response.Status < 0) {
                            $alert({ text: response.Message, title: $scope.Title });
                        } else {
                            $scope.state.item = response.Data;
                        }

                        $scope.popups.cancelamento.toggle();
                    } catch (error) {
                        $scope.tools.toastr.error("Não foi possível acessar o(s) servidor(es)");
                        console.error(error);
                    } finally {
                        $scope.popups.cancelamento.processando = false;
                        $scope.$digest();
                    }
                }
            },
            inutilizacao: {
                ativo: false,
                processando: false,
                toggle: async () => {
                    $scope.popups.inutilizacao.ativo = !$scope.popups.inutilizacao.ativo;
                },
                run: async () => {
                    try {
                        if ($scope.popups.inutilizacao.processando)
                            return;

                        $scope.popups.inutilizacao.processando = true;

                        const response = await saidaService.enviarInutilizacaoSefaz($scope.state.item);

                        if (response.Status < 0) {
                            $alert({ text: response.Message, title: $scope.Title });
                        } else {
                            $scope.state.item = response.Data;
                        }

                        $scope.popups.inutilizacao.toggle();
                    } catch (error) {
                        $scope.tools.toastr.error("Não foi possível acessar o(s) servidor(es)");
                        console.error(error);
                    } finally {
                        $scope.popups.inutilizacao.processando = false;
                        $scope.$digest();
                    }
                }
            },
            consulta: {
                ativo: false,
                processando: false,
                toggle: async () => {
                    $scope.popups.consulta.ativo = !$scope.popups.consulta.ativo;
                },
                run: async () => {
                    try {
                        if ($scope.popups.consulta.processando)
                            return;

                        $scope.popups.consulta.processando = true;

                        const response = await saidaService.enviarConsultaSefaz($scope.state.item);

                        if (response.Status < 0) {
                            $alert({ text: response.Message, title: $scope.Title });
                        } else {
                            $scope.state.item = response.Data;
                        }

                        $scope.popups.consulta.toggle();
                    } catch (error) {
                        $scope.tools.toastr.error("Não foi possível acessar o(s) servidor(es)");
                        console.error(error);
                    } finally {
                        $scope.popups.consulta.processando = false;
                        $scope.$digest();
                    }
                }
            },
        };
        $scope.auxiliar = {
            produto: {
                lookup: function (chaves) {
                    return $q.when(
                        lookupService
                            .getAllProduto({ chaves: chaves })
                            .then(function (response) {
                                if (response.Status < 0)
                                    $scope.tools.toastr.error(response.Message, "Serviço");
                                else {

                                    for (var index in response.Data) {
                                        response.Data[index].codigoProdutoOuBarras = response.Data[index].Codigo;
                                    }

                                    return response.Data;
                                }
                            })
                    );
                },
            },
            fornecedor: {
                lookup: function (chaves) {
                    return $q.when(
                        lookupService
                            .getAllFornecedor({ chaves: chaves })
                            .then(function (response) {
                                if (response.Status < 0)
                                    $scope.tools.toastr.error(response.Message, "Serviço");
                                else
                                    return response.Data;
                            })
                    );
                },
            },
            filial: {
                lookup: function (chaves) {
                    return $q.when(
                        lookupService
                            .getAllFilial({ chaves: chaves })
                            .then(function (response) {
                                if (response.Status < 0)
                                    $scope.tools.toastr.error(response.Message, "Serviço");
                                else
                                    return response.Data;
                            })
                    );
                },
            },
            transportadora: {
                lookup: function (chaves) {
                    return $q.when(
                        lookupService
                            .getAllTransportadora({ chaves: chaves })
                            .then(function (response) {
                                if (response.Status < 0)
                                    $scope.tools.toastr.error(response.Message, "Serviço");
                                else {
                                    ;
                                    return response.Data;
                                }

                            })
                    );
                },
            },
            tabelaPreco: {
                lookup: function (chaves) {
                    return $q.when(
                        lookupService
                            .getAllTabelaPreco({ chaves: chaves })
                            .then(function (response) {
                                if (response.Status < 0)
                                    $scope.tools.toastr.error(response.Message, "Serviço");
                                else
                                    return response.Data;
                            })
                    );
                },
            },
            condicaoPagamento: {
                lookup: function (chaves) {
                    return $q.when(

                        lookupService
                            .getAllcondicaoPagamento({ chaves: chaves })
                            .then(function (response) {
                                if (response.Status < 0) {
                                    $scope.tools.toastr.error(response.Message, "Serviço");
                                }
                                else
                                    return response.Data;
                            })
                    );
                },
            },
            naturezaOperacao: {
                lookup: function (chaves) {
                    return $q.when(
                        lookupService
                            .getAllNaturezaOperacao({ chaves: chaves })
                            .then(function (response) {
                                if (response.Status < 0)
                                    $scope.tools.toastr.error(response.Message, "Serviço");
                                else
                                    return response.Data;
                            })
                    );
                }
            },
            serie: {
                lookup: function (chaves) {

                    var filtro = {
                        Especie: {
                            NumeroModeloFiscal: 55
                        }
                    };


                    return $q.when(
                        lookupService
                            .getAllSerie({ chaves: chaves, filtro: filtro })
                            .then(function (response) {
                                if (response.Status < 0)
                                    $scope.tools.toastr.error(response.Message, "Serviço");
                                else
                                    return response.Data;
                            })
                    );
                },
                data: [],
                carregando: false,
                getAll: async () => {
                    if ($scope.auxiliar.serie.carregando)
                        return;

                    try {
                        $scope.auxiliar.serie.carregando = true;

                        const response = await serieNFService.getAll({ take: 9999 });

                        if (response.Status >= 0)
                            angular.copy(angular.fromJson(response.Data), $scope.auxiliar.serie.data);

                    } catch (error) {
                        $scope.tools.toastr.error("Não foi possível acessar o(s) servidor(es).");
                        console.error(error);

                    } finally {
                        $scope.auxiliar.serie.carregando = false;
                    }
                }
            },
            endereco: {
                prepare: function (index) {
                    contatoService
                        .prepareEndereco($scope.state.item.Enderecos[index])
                        .then(
                            function (response) {
                                if (response.Status < 0) {
                                    $scope.tools.toastr.error(response.Message, 'Serviço');
                                } else {
                                    $scope.state.item.Enderecos[index] = response.Data;
                                    $('[ng-model$="item.Linha2"]').focus();
                                }
                            },
                            function (_error) {
                                $scope.tools.toastr.error('Não foi possível acessar o(s) servidor(es)');
                            });
                },
                prepareNew: function () {
                    contatoService
                        .prepareNewEndereco($scope.state.item)
                        .then(
                            function (response) {
                                if (response.Status < 0) {
                                    $scope.tools.toastr.error(response.Message, 'Serviço');
                                } else {
                                    $scope.state.item = response.Data;
                                }
                            },
                            function (_error) {
                                $scope.tools.toastr.error('Não foi possível acessar o(s) servidor(es)');
                            });

                },
            },
            tipoFrete: {
                data: [
                    { Codigo: 0, Nome: "Por conta do emitente" },
                    { Codigo: 1, Nome: "Por conta do destinatário" },
                    { Codigo: 2, Nome: "Por conta de terceiros" },
                    { Codigo: 9, Nome: "Sem frete" }
                ]
            }
        };

        //[Inicializa funcões]
        $scope.initialize = function () {
            $scope.refresh();

            /*fix submit não estava funcionando em conjuto com o componente de auto-complete */
            //$(document).on('keypress', function (e) {
            //    if (e.which == 13 && $scope.popups.item.filtro.entity.codigoProdutoOuBarras) {
            //        e.preventDefault();
            //        $scope.popups.item.prepareNewItem();
            //    }
            //});

        };

        $scope.refresh = async () => {
            await $scope.get();
            $scope.$digest();
        };
        $scope.prepare = function () {

            saidaService
                .prepare($scope.state.item)
                .then(
                    function (response) {
                        if (response.Status < 0) {
                            $scope.tools.toastr.error(response.Message, 'Serviço');
                        } else {
                            $scope.state.item = response.Data;
                        }
                    },
                    function (_error) {
                        $scope.tools.toastr.error('Não foi possível acessar o(s) servidor(es)');
                    }
                );
        };

        $scope.get = async () => {

            if ($scope.state.carregando)
                return;

            try {

                $scope.state.carregando = true;
                $scope.state.vazio = false;

                const response = await saidaService.get($scope.state.item);

                if (response.Status < 0) {
                    $scope.tools.toastr.error(response.Message, 'Serviço');
                    console.error(response);
                } else {
                    $scope.state.item = response.Data;
                }
                $scope.state.vazio = !$scope.state.item;

            } catch (error) {
                $scope.tools.toastr.error('Não foi possível acessar o(s) servidor(es)');
                console.error(error);
            } finally {
                $scope.state.carregando = false;
            }
        };
        $scope.save = function () {
            $scope.state.processando = true;
            saidaService
                .save($scope.state.item)
                .then(
                    function (response) {
                        if (response.Status < 0) {
                            $alert({ text: response.Message, title: $scope.Title });
                        } else {
                            $scope.historyBack();
                        }
                        $scope.state.processando = false;
                    },
                    function (_error) {
                        $scope.state.processando = false;
                        $scope.tools.toastr.error('Não foi possível conectar com o(s) servidor(es)');
                    });
        };
        $scope.delete = function () {
            $scope.state.processando = true;
            saidaService
                .delete({ id: $scope.state.item.ID })
                .then(
                    function (response) {
                        if (response.Status < 0)
                            $alert({ title: $scope.Title, text: response.Message });
                        else {
                            $scope.state.item = response.Data;
                            $scope.historyBack();
                        }
                        $scope.state.processando = false;
                    },
                    function (error) {
                        $scope.state.processando = true;
                        $scope.tools.toastr.error(error, 'Não foi possível acessar o(s) servidor(es)');
                    }
                );
        };

        $scope.cancel = function () {
            $scope.tools.toastr.info('Cancelando saída...');
            saidaService
                .cancel({ id: $scope.state.item.ID })
                .then(
                    function (response) {
                        if (response.Status < 0)
                            $alert({ text: response.Message, title: $scope.Title });
                        else {
                            $scope.tools.toastr.clear();
                            $scope.tools.toastr.success("Saída cancelada.");
                            $scope.initialize();

                        }
                    },
                    function (error) {
                        $scope.tools.toastr.error(error, 'Não foi possível acessar o(s) servidor(es)');
                    }
                );
        };
        $scope.generateRomaneio = function () {
            $scope.tools.toastr.info('Efeivando movimentação de estoque...');
            $scope.state.salvado = true;
            saidaService
                .generateRomaneio({ id: $scope.state.item.ID })
                .then(
                    function (response) {
                        if (response.Status < 0)
                            $scope.tools.toastr.error(response.Message, "Serviço");
                        else {
                            $scope.tools.toastr.clear();
                            $scope.tools.toastr.success("Movimentação de estoque efetivada com êxito", "Serviço");
                            $scope.state.item = response.Data;
                        }
                        $scope.state.salvado = true;
                    },
                    function (error) {
                        $scope.tools.toastr.error(error, 'Não foi possível acessar o(s) servidor(es)');
                    }
                );
        };

        $scope.downloadAllXml = async () => {
            try {
                if ($scope.state.downloading)
                    return;

                $scope.state.downloading = true;

                const args = { filtro: { ID: $scope.state.item.NotaFiscal.ID } };
                const response = await notaFiscalService.downloadAllXml(args)

                if (!response.data.byteLength) {
                    $alert({ text: "Não foram encontrados XMLs para essa nota." });
                } else {
                    var blob = new Blob([response.data], { type: response.headers("content-type") });
                    var fileName = response.headers("content-disposition").toLowerCase().replace("attachment; filename=", "");

                    if (navigator.msSaveOrOpenBlob) {
                        navigator.msSaveOrOpenBlob(blob, fileName);
                    } else {
                        const a = document.createElement("a");
                        const url = window.URL.createObjectURL(blob);

                        document.body.appendChild(a);
                        a.href = url;
                        a.download = fileName;
                        a.style = "display:none";
                        a.click();

                        window.URL.revokeObjectURL(url);
                        a.remove();
                    }
                }
            } catch (error) {
                $scope.tools.toastr.error('Não foi possível conectar com o(s) servidor(es)');
                console.error(error);
            } finally {
                $scope.state.downloading = false;
                $scope.$digest();
            }
        };

        $scope.initialize();
    }

})();